#include "reconstruction_service.h"
#include <httplib.h>
#include <nlohmann/json.hpp>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgcodecs.hpp>
#include <vector>

using json = nlohmann::json;

class ReconstructionServer {
public:
    ReconstructionServer(const std::string& video_server_url = "http://host.docker.internal:5000")
        : reconstruction_service_(video_server_url) {
        
        setup_routes();
    }
    
    void run(int port = 8000) {
        std::cout << "Starting reconstruction server on port " << port << std::endl;
        std::cout << "Video server URL: " << reconstruction_service_.get_video_server_url() << std::endl;
        
        if (!server_.listen("0.0.0.0", port)) {
            std::cerr << "Failed to start server on port " << port << std::endl;
            return;
        }
        
        std::cout << "Server is running. Press Ctrl+C to stop." << std::endl;
    }

private:
    void setup_routes() {
        // 根路径 - API 文档
        server_.Get("/", [](const httplib::Request&, httplib::Response& res) {
            json api_doc = {
                {"status", "3D Reconstruction Service Running"},
                {"endpoints", {
                    {"/start", "Start reconstruction processing"},
                    {"/stop", "Stop reconstruction processing"},
                    {"/status", "Get processing status"},
                    {"/frame", "Get latest processed frame"},
                    {"/stats", "Get processing statistics"}
                }}
            };
            
            res.set_content(api_doc.dump(), "application/json");
        });
        
        // 启动处理
        server_.Get("/start", [this](const httplib::Request&, httplib::Response& res) {
            bool success = reconstruction_service_.start_processing();
            
            json response = {
                {"status", success ? "success" : "error"},
                {"message", success ? "三维重建处理已启动" : "无法启动处理"}
            };
            
            res.set_content(response.dump(), "application/json");
        });
        
        // 停止处理
        server_.Get("/stop", [this](const httplib::Request&, httplib::Response& res) {
            reconstruction_service_.stop_processing();
            
            json response = {
                {"status", "success"},
                {"message", "三维重建处理已停止"}
            };
            
            res.set_content(response.dump(), "application/json");
        });
        
        // 获取状态
        server_.Get("/status", [this](const httplib::Request&, httplib::Response& res) {
            auto stats = reconstruction_service_.get_processing_stats();
            
            json response = {
                {"status", "success"},
                {"is_processing", reconstruction_service_.is_processing()},
                {"video_server_connected", reconstruction_service_.check_video_server_status()},
                {"frames_processed", stats.frames_processed.load()},
                {"current_fps", stats.current_fps.load()}
            };
            
            res.set_content(response.dump(), "application/json");
        });
        
        // 获取最新帧
        server_.Get("/frame", [this](const httplib::Request&, httplib::Response& res) {
            auto frame_data = reconstruction_service_.get_latest_frame();
            
            if (frame_data) {
                // 编码处理后的帧
                std::vector<uchar> buffer;
                cv::imencode(".jpg", frame_data->processed_frame, buffer);
                
                json response = {
                    {"status", "success"},
                    {"frame", {
                        {"data", std::string(buffer.begin(), buffer.end())},
                        {"timestamp", frame_data->timestamp},
                        {"contours_count", frame_data->contours_count}
                    }}
                };
                
                res.set_content(response.dump(), "application/json");
            } else {
                json response = {
                    {"status", "error"},
                    {"message", "无可用帧"}
                };
                
                res.status = 404;
                res.set_content(response.dump(), "application/json");
            }
        });
        
        // 获取统计信息
        server_.Get("/stats", [this](const httplib::Request&, httplib::Response& res) {
            auto stats = reconstruction_service_.get_processing_stats();
            
            json response = {
                {"status", "success"},
                {"stats", {
                    {"frames_processed", stats.frames_processed.load()},
                    {"current_fps", stats.current_fps.load()},
                    {"processing_time_seconds", std::chrono::duration_cast<std::chrono::seconds>(
                        std::chrono::steady_clock::now() - stats.start_time).count()}
                }}
            };
            
            res.set_content(response.dump(), "application/json");
        });
    }
    
    ReconstructionService reconstruction_service_;
    httplib::Server server_;
};

int main(int argc, char* argv[]) {
    std::string video_server_url = "http://host.docker.internal:5000";
    int port = 8000;
    
    // 解析命令行参数
    for (int i = 1; i < argc; i++) {
        std::string arg = argv[i];
        if (arg == "--video-server" && i + 1 < argc) {
            video_server_url = argv[++i];
        } else if (arg == "--port" && i + 1 < argc) {
            port = std::stoi(argv[++i]);
        } else if (arg == "--help") {
            std::cout << "Usage: " << argv[0] << " [options]\n"
                      << "Options:\n"
                      << "  --video-server URL  Video server URL (default: http://host.docker.internal:5000)\n"
                      << "  --port PORT         Server port (default: 8000)\n"
                      << "  --help              Show this help message\n";
            return 0;
        }
    }
    
    try {
        ReconstructionServer server(video_server_url);
        server.run(port);
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    
    return 0;
} 